package com.bestcem.xm.deliver.controller.v2;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bestcem.xm.common.core.constant.ReqErrorCodeConstants;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.exception.BusinessException;
import com.bestcem.xm.deliver.controller.v2.param.EmailDeliversParam;
import com.bestcem.xm.deliver.controller.v2.param.SmsDeliversParam;
import com.bestcem.xm.deliver.entity.DeliverDeliver;
import com.bestcem.xm.deliver.enums.DeliverTtypeEnum;
import com.bestcem.xm.deliver.grpc.client.MemberGrpcClient;
import com.bestcem.xm.deliver.grpc.client.dto.MemberDto;
import com.bestcem.xm.deliver.grpc.client.dto.MemberProjectDto;
import com.bestcem.xm.deliver.service.DeliverDeliverService;
import com.bestcem.xm.deliver.service.DeliverEmailDeliverService;
import com.bestcem.xm.deliver.service.DeliverSmsDeliverService;
import com.bestcem.xm.deliver.util.CommonUtil;
import com.bestcem.xm.deliver.util.DeliverConstant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;


@Slf4j
@Api(tags = "投放-V2")
@RestController
@RequiredArgsConstructor
@RequestMapping("/deliver/v2/")
public class DeliverV2Controller {

    private @NonNull MemberGrpcClient memberGrpcClient;

    private @NonNull DeliverDeliverService deliverDeliverService;
    private @NonNull DeliverSmsDeliverService smsDeliverService;
    private @NonNull DeliverEmailDeliverService emailDeliverService;


    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "page", value = "页码"),
            @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "rowsPerPage", value = "每页条数")
    })
    @ApiOperation(value = "获取投放的免打扰联系人详情列表")
    @GetMapping("/disturb/member/detail/{id:[a-fA-F0-9]{24}}")
    public JSONObject getDisturbMemberDetail(@PathVariable String id, @ApiIgnore Page<?> page) {
        JSONObject ret = new JSONObject();
        DeliverDeliver deliver = Optional.ofNullable(deliverDeliverService.getById(id))
                .orElseThrow(() -> new BusinessException(String.format("Deliver[id=%s] not found", id)));

        Object base = deliverDeliverService.getBaseAndMemberIdListByDeliverId(id, DeliverTtypeEnum.getEnumByLambda(deliver.getTtype()));
        JSONObject result = JSONObject.parseObject(JSONObject.toJSONString(base));
        JSONArray mids = result.getJSONArray("member_id_list");
        int c = !mids.isEmpty() ? mids.size() : 0;
        result.put("count", c);

        if (deliver.getTtype().equals(DeliverTtypeEnum.DELIVER_TTYPE_SMS.getValue())) {
            JSONArray mpms = result.getJSONArray("mproject_mobile");
            int f = !mpms.isEmpty() ? mids.size() : 0;
            result.put("p_count", f);
        }

        String flag = Optional.ofNullable(result.getJSONObject("filter_params"))
                .map(filter_params -> filter_params.getString("is_mproject"))
                .orElse("");
        //todo python 做了手机号隐藏，这里没写，这个接口好像没卵用
        if (StrUtil.isNotEmpty(flag)) {
            int total_count = result.getIntValue("p_count");
            int startIndex = (int) ((page.getCurrent() - 1) * page.getSize());
            int endIndex = (int) Math.min(startIndex + page.getSize(), total_count);
            List<String> mproject_ids = result.getJSONArray("mproject_mobile").toJavaList(String.class).subList(startIndex, endIndex);

            List<MemberProjectDto> details_mproject = new ArrayList<>();
            if (!CollectionUtils.isEmpty(mproject_ids)) {
                details_mproject = memberGrpcClient.listProjectsByIds(mproject_ids);
            }

            ret.put("total_count", total_count);
            ret.put("rows", details_mproject);
            ret.put("page", page.getCurrent());
            ret.put("is_mproject", true);
        } else {
            int total_count = result.getIntValue("count");
            int startIndex = (int) ((page.getCurrent() - 1) * page.getSize());
            int endIndex = (int) Math.min(startIndex + page.getSize(), total_count);
            List<String> member_ids = mids.toJavaList(String.class).subList(startIndex, endIndex);

            List<MemberDto> details_member = new ArrayList<>();
            if (!CollectionUtils.isEmpty(member_ids)) {
                details_member = memberGrpcClient.listMembersByIds(member_ids);
            }

            ret.put("total_count", total_count);
            ret.put("rows", details_member);
            ret.put("page", page.getCurrent());
            ret.put("is_mproject", false);
        }

        return ret;
    }

    @ApiOperation(value = "邮件投放-上传名单-下载模板")
    @GetMapping("/member/template/")
    public void deliverMemberTemplate(@RequestParam(value = "template_name", required = false) String templateName, HttpServletResponse response) {
        InputStream in = null;
        ServletOutputStream out = null;
        try {
            templateName = DeliverConstant.DELIVER_EXCEL_MAP.get(templateName);
            in = ResourceUtil.getStream("file/excel/" + templateName + ".xlsx");
            response.reset();
            response.setContentType("application/x-msdownload");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(templateName + ".xlsx", "utf-8"));
            out = response.getOutputStream();

            IOUtils.copy(in, out);
        } catch (IOException e) {
            log.error("模板下载失败", e);
        } finally {
            IOUtils.closeQuietly(out);
            IOUtils.closeQuietly(in);
        }
    }

    @ApiOperation(value = "邮件投放-上传名单")
    @PostMapping("/member/ind/deliver/import/")
    public XmResultJson<?> memberDeliverImport(@RequestParam(value = "primary_key", required = false) String primaryKey,
                                               @RequestParam(value = "files", required = false) MultipartFile files,
                                               @RequestParam(value = "deliver_id", required = false) String deliverId) {
        if (Objects.isNull(files)) {
            return XmResultJson.fail(ReqErrorCodeConstants.PARAM_LOST, ":file is lost");
        }
        ServiceResult<?> res = CommonUtil.checkExt(files.getOriginalFilename(), "excel");
        if (!res.isSuccess()) {
            return XmResultJson.fail(Integer.valueOf(res.getErrorCode()), res.getMsg());
        }
        return XmResultJson.handleServiceResult(deliverDeliverService.memberDeliverImport(files, deliverId, "mobile".equals(primaryKey)));
    }

    @ApiOperation(value = "邮件投放-新增")
    @PostMapping("/emaildelivers")
    public XmResultJson<?> emailDelivers(@RequestBody EmailDeliversParam param) {
        return XmResultJson.handleServiceResult(emailDeliverService.emailDelivers(param));
    }

    @ApiOperation(value = "短信投放-新增")
    @PostMapping("/smsdelivers")
    public XmResultJson<?> smsDelivers(@RequestBody SmsDeliversParam param) {
        return XmResultJson.handleServiceResult(smsDeliverService.smsDelivers(param));
    }
}
